
#include "Engine.h"
#include "Ship.h"
#include "Utils/Vector2D.h"
#include "Graphics/ParticleSystem/ParticleSystem.h"
#include "Graphics/ParticleSystem/ParticleEmitter.h"

#include <cassert>
#include <cmath>

Engine::Engine(Ship *pship) : 
    parent_ship(pship), 
    thrusting(false), 
    afterburning(false) {
    
    assert(parent_ship != NULL);
    
    Vector2D position = parent_ship->position;
    Vector2D heading = parent_ship->heading;
    float size = parent_ship->size;

    engine_emitter = new ParticleEmitter(position-(size*0.6f)*heading, 
                                         -1.5f*heading, 
                                         0.20f, 0.0f, 
                                         250, 
                                         0.3f, 0.6f, 1.0f, 
                                         1.0f, 0.1f, 
                                         0.09f, 0.0f, 
                                         7.0f, 1.0f,
                                         0.0f, 0.0f,
                                         "data/Cloud.png");

    afterburner_emitter = new ParticleEmitter(position-(size*0.75f)*heading, 
                                              -2.0f*heading, 
                                              0.3f, 0.0f, 
                                              250, 
                                              1.0f, 0.5f, 0.2f, 
                                              1.0f, 0.1f, 
                                              0.1f, 0.0f, 
                                              7.0f, 0.5f,
                                              0.0f, 0.0f,
                                              "data/Cloud.png");

    std::vector<ParticleEmitter*> emitters;
    emitters.push_back(engine_emitter);
    emitters.push_back(afterburner_emitter);

    engine_psys = new ParticleSystem(emitters);
}


Engine::~Engine(){
    delete engine_psys;
}

void Engine::accelerate(float how_much, bool afterburn){
    if (afterburn) afterburning = true;
#if defined(WASD_ABS)
    if (afterburning) {
        parent_ship->velocity.add(parent_ship->heading*parent_ship->acceleration*how_much*Timer::secondsSinceLastFrame());
        thrusting = false;
    } else {
        Vector2D head(0,how_much);
        parent_ship->velocity.add(head*parent_ship->acceleration*Timer::secondsSinceLastFrame());
        thrusting = true;
    }
#elif defined(WASD_REL)
    parent_ship->velocity.add(parent_ship->heading*parent_ship->acceleration*how_much*Timer::secondsSinceLastFrame());
    if (!afterburn)
        thrusting = true;
#else
    #error "Define either WASD_REL or WASD_ABS"
#endif
    //parent_ship->velocity.add(parent_ship->heading*parent_ship->acceleration*how_much*
    //                          Timer::secondsSinceLastFrame());
}

void Engine::side_thrust(float how_much){
#if defined(WASD_ABS)
    Vector2D head(how_much,0);
    parent_ship->velocity.add(head*parent_ship->acceleration*Timer::secondsSinceLastFrame());
#elif defined(WASD_REL)
    Vector2D head = parent_ship->heading;
    head.rotate(-90);
    parent_ship->velocity.add(head*parent_ship->acceleration*how_much*Timer::secondsSinceLastFrame());
#else
    #error "Define either WASD_REL or WASD_ABS"
#endif
    thrusting = true;
}

void Engine::update(void){
    engine_emitter->setEmitterPosition(parent_ship->position - (parent_ship->size*0.6f)*parent_ship->heading);
    engine_emitter->setEmitVelocity((-1.5f * parent_ship->heading) + parent_ship->velocity);

    afterburner_emitter->setEmitterPosition(parent_ship->position - (parent_ship->size*0.75f)*parent_ship->heading);
    afterburner_emitter->setEmitVelocity((-2.0f * parent_ship->heading) + parent_ship->velocity);

    engine_psys->update();

    if(!thrusting){ engine_emitter->stop(); }
    else{ engine_emitter->start(); }
    thrusting = false;

    if(!afterburning){ afterburner_emitter->stop(); }
    else{ afterburner_emitter->start(); }
    afterburning = false;
}


void Engine::render(void){
    engine_psys->render();
}

